package com.join.template.core.grammar.tool;

import com.join.template.core.configuration.JoinConfig;
import com.join.template.core.constant.EntityType;
import com.join.template.core.example.Example;
import com.join.template.core.grammar.config.GenerateConfig;
import com.join.template.core.grammar.generate.Generate;
import com.join.template.core.grammar.handle.Grammar;
import com.join.template.core.factory.JoinFactory;
import com.join.template.core.grammar.info.FieldGenerateInfo;
import com.join.template.core.grammar.info.GrammarInfo;
import com.join.template.core.listener.GenerateListener;
import com.join.template.core.util.Assert;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


public abstract class AbstractTool implements GrammarTool {

    protected JoinFactory joinFactory;

    protected JoinConfig configuration;

    protected GenerateListener generateListener;

    protected GenerateConfig generateConfig;

    protected Class<? extends GrammarInfo> grammarInfoClass;

    protected Generate generate;

    @Override
    public AbstractTool setJoinFactory(JoinFactory joinFactory) {
        this.joinFactory = joinFactory;
        this.configuration = joinFactory.getConfiguration();
        return this;
    }

    @Override
    public AbstractTool setGenerateListener(GenerateListener generateListener) {
        this.generateListener = generateListener;
        return this;
    }

    @Override
    public AbstractTool setGenerateConfig(GenerateConfig generateConfig) {
        this.generateConfig = generateConfig;
        return this;
    }

    @Override
    public AbstractTool setGrammarInfoClass(Class grammarInfoClass) {
        this.grammarInfoClass = grammarInfoClass;
        return this;
    }

    @Override
    public Generate createGenerate(Class bean) {
        Assert.isNull(generateConfig, "请设置生成配置");
        if (this.grammarInfoClass == null) {
            this.grammarInfoClass = FieldGenerateInfo.class;
        }
        generate = joinFactory.createGenerate(bean);
        generate.setGenerateListener(generateListener);
        generate.setGenerateConfig(generateConfig);
        generate.setGrammarInfoClass(grammarInfoClass);
        return generate;
    }

    @Override
    public AbstractTool generate(String name, EntityType type, String describe, List bean) {
        Assert.isNull(generate, "未创建生成器");
        generate.generate(name, type, describe, bean);
        return this;
    }

    @Override
    public AbstractTool generate(Object child) {
        Assert.isNull(generate, "未创建生成器");
        generate.generate(child);
        return this;
    }


    @Override
    public List<? extends GrammarInfo> getGrammarInfos() {
        Assert.isNull(generate, "未创建生成器");
        return generate.getGrammarInfos();
    }


    @Override
    public Map<Integer, String> generateExample() {
        Map<Integer, String> grammars = new HashMap();
        Map<Object, Grammar> exprHandles = joinFactory.getGrammar();
        for (Grammar expressionHandle : exprHandles.values()) {
            Example example = expressionHandle.getExample();
            if (example != null) {
                grammars.put(expressionHandle.getNodeType(), example.getExample());
            }
        }
        return grammars;
    }


}
